/*
 * CS_PARTY_INVITE_RES.cpp
 *
 *  Created on: 2013. 5. 21.
 *      Author: the2
 */

#include "../../Command.h"

#include "../../User.h"

#include "../../NLogic/Static.h"
#include "../../NLogic/Battle.h"

namespace ProjectZ { namespace NCommand {

void sendPartyJoinInfo(User * pMaster, int gid)
{
	/*
	 * // 초대/대기 팝업 공통
	// 파티 맴버 조인시 서버에서 자동으로 내려 줌
	SC_PARTY_JOIN_INFO					0x1120
	{
		u32 gid;
	}
	 */

//	::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
//	* pNoti << gid;
//	pNoti->MakePacket(CMD_SC_PARTY_JOIN_INFO);
//	pMaster->Send(pNoti, 1);

	if (NULL == pMaster)
		return;

	NLogic::Party * pParty = pMaster->GetParty();
	if (NULL == pParty)
		return;

	auto Tree = pParty->GetAllUserTree();

	//int count = Tree.size();

	std::for_each(Tree.begin(), Tree.end(), [&](NLogic::Party::USERTREE::value_type & pair) {
		::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
		* pNoti << gid;
		DEBUGLOG("send party join %s", pair.second->GetUserInfo().nickname.c_str());
		pNoti->MakePacket(CMD_SC_PARTY_JOIN_INFO);
		pair.second->Send(pNoti, 1);
	} );
}

void sendPartyCreateDone(int ack, User * pMaster)
{
	/*
	 * //수락 성공 여부, 유저 목록 전송
	SN_PARTY_CREATE_DONE				0x111f
	{
		s16	ack;				/// 1:완료 ,  -1 실패
		u8	count				/// 수락한 유저 수
		{
			u32	u32gid;			/// 수락한 유저의 gid
		}
	}
	 */

	::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pNoti << static_cast<int16_t>(ack);
	* pNoti << static_cast<uint8_t>(pMaster->GetParty()->GetAcceptCount() + 1);	// +1 = chief
	* pNoti << pMaster->GetUserSeq();

	std::for_each(pMaster->GetParty()->GetAcceptUserTree().begin(), pMaster->GetParty()->GetAcceptUserTree().end(), [&](const std::pair<int, User *> & pair) {
		if (true == pair.second->GetPartyAccept())
		{
			* pNoti << pair.first;
		}
	} );

	pNoti->MakePacket(CMD_SN_PARTY_CREATE_DONE);
	pMaster->GetSpace()->SendAll(pNoti);
}

void Command::CS_PARTY_INVITE_RES(User * pUser, ::Network::Packet * pPacket)
{
	/*
	 * CS_PARTY_INVITE_RES		0x1104
	{
		u32	party_seq;
		u8	answer;			// 0:no, 1:yes
	}

	SC_PARTY_INVITE_RES		0x1105 => 사용안함
	{
		u32	target_user_gid;
		u8	answer;			// 0:no, 1:yes
	}
	 */

	STRESSLOG("CS_PARTY_INVITE_RES");

	NLogic::Space * pWorld = pUser->GetSpace();
	if (NULL == pWorld)
	{
		pUser->SetEnumState(User::EnumState::__NONE__);
		DEBUGLOG("CS_PARTY_INVITE_RES NULL == pWorld");
		return;
	}

	if (pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD)
	{
		pUser->SetEnumState(User::EnumState::__NONE__);
		DEBUGLOG("CS_PARTY_INVITE_RES pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD");
		return;
	}

	PREPARE_PACKET;

	int space_seq = 0;
	uint8_t answer = 0;

	* pPacket >> space_seq >> answer;

	auto itr = NLogic::Static::Instance().GETSPACETREE().find(space_seq);
	if (itr == NLogic::Static::Instance().GETSPACETREE().end())
	{
		pUser->SetEnumState(User::EnumState::__NONE__);
		DEBUGLOG("CS_PARTY_INVITE_RES NLogic::Space * pDungeon IS NULL");
		return;
	}

	NLogic::Space * pDungeon = itr->second;
	User * pMaster = pDungeon->GetMaster();
	if (NULL == pMaster)
	{
		pUser->SetEnumState(User::EnumState::__NONE__);
		DEBUGLOG("CS_PARTY_INVITE_RES NULL == pChief");
		return;
	}

	if (NULL == pMaster->GetParty())
	{
		pUser->SetEnumState(User::EnumState::__NONE__);
		DEBUGLOG("CS_PARTY_INVITE_RES NULL == pChief's Party");
		return;
	}

	NLogic::Party * pParty = pUser->GetParty();
	if (NULL == pParty)
	{
		pUser->SetEnumState(User::EnumState::__NONE__);
		DEBUGLOG("CS_PARTY_INVITE_RES NULL == pParty");
		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		* pAck << static_cast<int16_t>(ACK_NOT_PARTY);
		pAck->MakePacket(CMD_SC_PARTY_INVITE_RES);
		pUser->Send(pAck);
		return;
	}

	auto finditr = pParty->GetInviteUserTree().find(pUser->GetUserSeq());
	if (finditr == pParty->GetInviteUserTree().end())
	{
		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		* pAck << static_cast<int16_t>(ACK_NOT_PARTY);
		pAck->MakePacket(CMD_SC_PARTY_INVITE_RES);
		pUser->Send(pAck);

		return;
	}

	if (pParty->GetState() != NLogic::Party::State::ACCEPT_WAIT)
	{
		pUser->SetEnumState(User::EnumState::__NONE__);
		DEBUGLOG("CS_PARTY_INVITE_RES pParty->GetState() != NLogic::Party::State::ACCEPT_WAI");

		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		* pAck << static_cast<int16_t>(ACK_START_BATTLE);
		pAck->MakePacket(CMD_SC_PARTY_INVITE_RES);
		pUser->Send(pAck);
		return;
	}

	if (0 == answer)
	{
		pUser->SetEnumState(User::EnumState::__NONE__);

		pParty->LeaveUser(pUser);
		pParty->AddRefuseCount();

		return;
	}

	pWorld->LeaveUser(pUser);

	pUser->SetEnumState(User::EnumState::READY_WAIT);
	pParty->AddAcceptUserTree(pUser);

	pUser->GetBattle()->GetData().bReadyFight = false;

	::Network::Packet * pDungeonInfo = pDungeon->GetDetailInfoPacket();
	if (NULL == pDungeonInfo)
	{
		pUser->SetEnumState(User::EnumState::__NONE__);

		pParty->LeaveUser(pUser);
		pParty->AddRefuseCount();

		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		* pAck << static_cast<int16_t>(ACK_NOT_PARTY);
		pAck->MakePacket(CMD_SC_PARTY_INVITE_RES);
		pUser->Send(pAck);

		return;
	}
	//int refCount = pDungeonInfo->GetRefrenceCount();
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	pAck->WriteBin(pDungeonInfo->GetPtr()+6, pDungeonInfo->GetEndLen()-6);
	pAck->MakePacket(CMD_SN_DUNGEON_DETAIL_INFO);
	pUser->Send(pAck);

	pDungeon->EnterUser(pUser);

	sendPartyJoinInfo(pMaster, pUser->GetUserSeq());

	if (pParty->GetInviteUserTree().size() == 0 || pParty->GetAcceptUserTree().size() >= MAX_PARTY_DUNGEON_INVITE + 1)
	{
		//pParty->SetPartyFull();
		sendPartyCreateDone(ACK_OK, pMaster);
		pParty->SetState(NLogic::Party::State::READY_WAIT);

		//pParty->AddAcceptUserTree(pParty->GetMaster());
		pParty->GetMaster()->SetEnumState(User::EnumState::READY_WAIT);

		return;
	}

	//unsigned int total = pParty->GetAcceptCount() + pParty->GetRefuseCount();
//	if (pParty->GetInviteUserTree().size() <= pParty->GetAcceptUserTree().size())
//	{
//		pParty->SetPartyFull();
//		sendPartyCreateDone(ACK_OK, pMaster);
//		pParty->SetState(NLogic::Party::State::READY_WAIT);
//
//		pParty->AddAcceptUserTree(pParty->GetMaster());
//		pParty->GetMaster()->SetEnumState(User::EnumState::READY_WAIT);
//
//		return;
//	}
}

} /*NCommand*/ } /*ProjectZ*/
